import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.servlet.ModelAndView;

import com.jadcon.bedbreakfast.domain.Reservation;
import com.jadcon.bedbreakfast.domain.ReservationRepository;
import com.jadcon.bedbreakfast.domain.ReservationRepositoryInMemoryImpl;
import com.jadcon.bedbreakfast.domain.ReservationServiceImpl;
import com.jadcon.bedbreakfast.domain.SuiteRepository;
import com.jadcon.bedbreakfast.domain.SuiteRepositoryInMemoryImpl;
import com.jadcon.bedbreakfast.domain.SuiteServiceImpl;
import com.jadcon.bedbreakfast.web.ViewReservationController;


public class DependencyInjectionTest {

	public static void main(String args[]) {
		noContainer();
		fallContainer();
		springContainer();
	}
	
	public static void noContainer() {
		// we don't need to stinkin' spring!!!
		
		// instantiate the objects
		ReservationRepository reservationRepository = new ReservationRepositoryInMemoryImpl();
		SuiteRepository suiteRepository = new SuiteRepositoryInMemoryImpl();
		
		ReservationServiceImpl reservationService = new ReservationServiceImpl();
		SuiteServiceImpl suiteService = new SuiteServiceImpl();
		
		ViewReservationController controller = new ViewReservationController();
		
		// wire them together
		suiteService.setSuiteRepository(suiteRepository);
		
		reservationService.setReservationRepository(reservationRepository);
		reservationService.setSuiteService(suiteService);
		
		controller.setReservationService(reservationService);
		
		// call the controller
		ModelAndView mav = controller.findReservationByRoom(101);
		List<Reservation> reservationList = (List<Reservation>)mav.getModel().get("reservationList");
		System.out.println("noContainer: " + reservationList.size() + " reservations found");
	}
	
	public static void fallContainer() {
		// fall is better than spring
		
		// create bean definitions
		BeanDefinition reservationRepoDef = new BeanDefinition("reservationRepository", "com.jadcon.bedbreakfast.domain.ReservationRepositoryInMemoryImpl");
		BeanDefinition suiteRepoDef = new BeanDefinition("suiteRepository", "com.jadcon.bedbreakfast.domain.SuiteRepositoryInMemoryImpl");
		
		// repository is wired into the service
		BeanDefinition reservationServiceDef = new BeanDefinition("reservationService", "com.jadcon.bedbreakfast.domain.ReservationServiceImpl");
		reservationServiceDef.getPropertyList().add(new BeanProperty("setReservationRepository", "reservationRepository"));
		reservationServiceDef.getPropertyList().add(new BeanProperty("setSuiteService", "suiteService"));
		
		BeanDefinition suiteServiceDef = new BeanDefinition("suiteService", "com.jadcon.bedbreakfast.domain.SuiteServiceImpl");
		suiteServiceDef.getPropertyList().add(new BeanProperty("setSuiteRepository", "suiteRepository"));
		
		BeanDefinition viewReservationControllerDef = new BeanDefinition("viewReservationController", "com.jadcon.bedbreakfast.web.ViewReservationController");
		viewReservationControllerDef.getPropertyList().add(new BeanProperty("setReservationService", "reservationService"));
		
		// create container and add bean definitions
		FallContainer fall = new FallContainer();
		fall.add(reservationRepoDef);
		fall.add(suiteRepoDef);
		fall.add(reservationServiceDef);
		fall.add(suiteServiceDef);
		fall.add(viewReservationControllerDef);
		
		fall.initialize();
		
		// call the controller
		ViewReservationController controller = (ViewReservationController)fall.getBean("viewReservationController");
		ModelAndView mav = controller.findReservationByRoom(101);
		List<Reservation> reservationList = (List<Reservation>)mav.getModel().get("reservationList");
		System.out.println("fallContainer: " + reservationList.size() + " reservations found");
		
	}
	
	public static void springContainer() {
		// actually spring is much better than fall
		ApplicationContext spring = new ClassPathXmlApplicationContext("test-spring-config.xml");
		ViewReservationController controller = (ViewReservationController)spring.getBean("viewReservationController");
		ModelAndView mav = controller.findReservationByRoom(101);
		List<Reservation> reservationList = (List<Reservation>)mav.getModel().get("reservationList");
		System.out.println("springContainer: " + reservationList.size() + " reservations found");
	}
}

